package com.jee.ssm.modules.handheldMachine;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.jee.ssm.common.QRCode.ZXingBackGroundUtils;
import com.jee.ssm.common.config.Logger;
import com.jee.ssm.model.Order;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.order.services.OrderService;
import org.jdom.JDOMException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * 支付宝生成支付二维码
 */
@Controller
@RequestMapping("/alipayCode")
public class AlipayCode {

    @Resource
    private OrderService orderService;

    /**
     * 生成支付二维码的链接
     * @param orderId　订单的编号
     * @param
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    @RequestMapping("/uniformOrder")
    @ResponseBody
    public Tip uniformOrder(String orderId,HttpServletRequest req) throws AlipayApiException {
        System.out.println("--------------------扫描支付统一下单中-------------------------");
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.HTTPURL,AlipayConfig.APPId,AlipayConfig.PRIVATEKEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.ALIPAYPUBLICKEY,AlipayConfig.signType);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
//        String out_trade_no =orderId+"_"+ (int)(Math.random()*100) ;
       Order order = orderService.selectById(orderId);
       if(order ==null){
           return  new Tip(2,"暂未获取到订单信息");
       }
//       double totalFee = order.getOrderMoney();//正式上线后
        double totalFee = 0.01;//测试
        String out_trade_no =orderId ;
        String subject ="停车场支付";
        String param ="{" +
                "\"out_trade_no\":\""+out_trade_no+"\","+
                "\"total_amount\":"+totalFee+","+
                "\"subject\":\""+subject+"\""+
                "  }";
        request.setBizContent(param);
        request.setNotifyUrl(AlipayConfig.CALLBACKURL); //回调路径
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            String  qrCode = response.getQrCode();
            String baseUrl = req.getSession().getServletContext().getRealPath(""); //获取到项目的真是路径
            String payUrl ="/images/qrcode/zfb_"+out_trade_no+".jpg";
            System.out.println(qrCode);
            boolean b = ZXingBackGroundUtils.drawLogoQRCode(baseUrl+"/images/icon/alipayLogo.jpg",baseUrl+payUrl,qrCode);
            if(b){
                return  new Tip((Object) payUrl,"支付宝支付二维码生成成功");
            }else{
                return  new Tip(2,"支付宝支付二维码生成失败");
            }
        }else{
            return  new Tip(2,response.getSubMsg());
        }
    }


    /**
     * <pre>
     * 第一步:验证签名,签名通过后进行第二步
     * 第二步:按一下步骤进行验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     * </pre>
     *
     * @param
     * @return
     */
    @RequestMapping("/callback")
    @ResponseBody
    public String callback(HttpServletRequest request) {
        System.out.println("--------------支付宝支付回调----------------");
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
        Logger.info("支付宝支付成功回调信息"+paramsJson);
        try {
//            AlipayConfig alipayConfig = new AlipayConfig();// 支付宝配置
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAYPUBLICKEY,
                    AlipayConfig.CHARSET, AlipayConfig.signType);
            if (signVerified) {
                Logger.info("支付宝回调签名认证成功");
                String outTradeNo = params.get("out_trade_no");
                orderService.handleCallBack(outTradeNo,0,request,"zfb_");
                return "success";
            } else {
                Logger.info("支付宝回调签名认证失败，signVerified=false, paramsJson:{}"+paramsJson);
                return "failure";
            }
        } catch (AlipayApiException e) {
            Logger.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}"+ paramsJson+"----------"+ e.getMessage());
            return "failure";
        }
    }

    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }

}
